package de.hwrBerlin.dataMining.controller.connectors;

import java.io.File;
import java.io.FileWriter;
import org.dom4j.Document;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.widgets.Shell;

import de.hwrBerlin.dataMining.dataStructure.DecisionTreeNode;
import de.hwrBerlin.dataMining.view.TreePainter;
import de.hwrBerlin.dataMining.view.dialog.TreeExportZoom;
import de.hwrBerlin.tools.logger.LogLevel;
import de.hwrBerlin.tools.logger.Logger;

public abstract class TreeFileReaderWriter {
    
    public static boolean writeTreeToTextFile(DecisionTreeNode pTreeNode, File pFile) {
        if(pTreeNode == null) {
            Logger.log(LogLevel.ERROR, "Es kann kein null-Object als Baum abgespeichert werden");
            return false;
        }
        if(pFile == null) {
            Logger.log(LogLevel.ERROR, "Der Baum kann nicht abgespeichert werden, die Datei ist fehlerhaft");
            return false;

        }
        // Schreibe Datei
        try {
            
            OutputFormat format = OutputFormat.createPrettyPrint();
            format.setEncoding(System.getProperty("file.encoding"));
            XMLWriter writer = new XMLWriter(new FileWriter(pFile), format);
            writer.write(pTreeNode.toXML());
            writer.close();
            return true;
        }
        
        catch (Exception e) {
            Logger.log(LogLevel.ERROR, "Fehler beim Schreiben einer Text-Baumdatei: " + pFile);
            e.printStackTrace();
            return false;
        }
    }
    
    public static boolean writeTreeToImageFile(DecisionTreeNode pTreeNode, File pFile) {
        if(pTreeNode == null) {
            Logger.log(LogLevel.ERROR, "Es kann kein null-Object als Baum abgespeichert werden");
            return false;
        }
        if(pFile == null) {
            Logger.log(LogLevel.ERROR, "Der Baum kann nicht abgespeichert werden, die Datei ist fehlerhaft");
            return false;

        }
        // Schreibe Datei
        try {
            Shell shell = new Shell();
            TreeExportZoom treeExportZoom = new TreeExportZoom(shell, SWT.NONE);
            TreePainter treePainter = treeExportZoom.open(pTreeNode);
            
            if(treePainter != null){
                int format;
                if(FileType.getFileType(pFile) == FileType.JPEG){
                    format = SWT.IMAGE_JPEG;
                }
                else{
                    format = SWT.IMAGE_PNG;
                }
                
                ImageLoader iLoader = new ImageLoader();
                
                iLoader.data = new ImageData[] { treePainter.toImage().getImageData() };
                iLoader.save(pFile.getAbsolutePath(), format);
                
                shell.dispose();
                return true;
            }
            
            return false;
        }
        
        catch (Exception e) {
            Logger.log(LogLevel.ERROR, "Fehler beim Schreiben einer Bild-Baumdatei: " + pFile);
            e.printStackTrace();
            return false;
        }
    }
    
    public static boolean writeTreeToSVGFile(DecisionTreeNode pTreeNode, File pFile) {
        if(pTreeNode == null) {
            Logger.log(LogLevel.ERROR, "Es kann kein null-Object als Baum abgespeichert werden");
            return false;
        }
        if(pFile == null) {
            Logger.log(LogLevel.ERROR, "Der Baum kann nicht abgespeichert werden, die Datei ist fehlerhaft");
            return false;

        }
        // Schreibe Datei
        try {
            Shell shell = new Shell();
            TreeExportZoom treeExportZoom = new TreeExportZoom(shell, SWT.NONE);
            TreePainter treePainter = treeExportZoom.open(pTreeNode);
            
            if(treePainter != null){
                OutputFormat format = OutputFormat.createPrettyPrint();
                format.setEncoding(System.getProperty("file.encoding"));
                XMLWriter writer = new XMLWriter(new FileWriter(pFile), format);
                writer.write(treePainter.toSVG());
                writer.close();
                
                //Alles hat geklappt
                return true;
            }
            
            return false;
        }
        
        catch (Exception e) {
            Logger.log(LogLevel.ERROR, "Fehler beim Schreiben einer Text-Baumdatei: " + pFile);
            e.printStackTrace();
            return false;
        }
    }
    
    /**
     * Erstellt aus einer xml-Datei ein DecisionTree 
     * @param pFile
     * @return
     */
    public static DecisionTreeNode getDecisionTreeFromFile(File pFile) {
        if (pFile.exists()) {
            try {
                SAXReader reader = new SAXReader();
                Document document = reader.read(pFile);
                
                return new DecisionTreeNode(document);
            }
            catch (Exception e) {
                Logger.log(LogLevel.ERROR, "Konnte die BaumXML nicht lesen von: " + pFile + " - Encoding muss " + System.getProperty("file.encoding") + " sein.");
                e.printStackTrace();
                return null;
            }
        }
        // Die Datei existiert garnicht
        else {
            Logger.log(LogLevel.ERROR, "Die BaumXML wurde nicht gefunden: " + pFile);
            return null;
        }
    }
}

